home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / 3Dfx / demos / teapot.c < prev    next >
C/C++ Source or Header  |  1998-12-15  |  12KB  |  598 lines

  1. /*
  2.  * This program is under the GNU GPL.
  3.  * Use at your own risk.
  4.  *
  5.  * written by David Bucciarelli (tech.hmw@plus.it)
  6.  *            Humanware s.r.l.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <math.h>
  12. #include <time.h>
  13.  
  14. #ifdef WIN32
  15. #include <windows.h>
  16. #endif
  17.  
  18. #include <GL/glut.h>
  19.  
  20. #include "image.h"
  21.  
  22. #ifdef XMESA
  23. #include "GL/xmesa.h"
  24. static int fullscreen=1;
  25. #endif
  26.  
  27. static int WIDTH=640;
  28. static int HEIGHT=480;
  29.  
  30. #define FRAME 50
  31.  
  32. #define BASESIZE 10.0
  33.  
  34. #define BASERES 12
  35. #define TEAPOTRES 3
  36.  
  37. #ifndef M_PI
  38. #define M_PI 3.1415926535
  39. #endif
  40.  
  41. extern void teapot(GLint, GLdouble, GLenum);
  42. extern void shadowmatrix(GLfloat [4][4], GLfloat [4], GLfloat [4]);
  43. extern void findplane(GLfloat [4], GLfloat [3], GLfloat [3], GLfloat [3]);
  44.  
  45.  
  46. static int win=0;
  47.  
  48. static float obs[3]={5.0,0.0,1.0};
  49. static float dir[3];
  50. static float v=0.0;
  51. static float alpha=-90.0;
  52. static float beta=90.0;
  53.  
  54. static GLfloat baseshadow[4][4];
  55. static GLfloat lightpos[4]={2.3,0.0,3.0,1.0};
  56. static GLfloat lightdir[3]={-2.3,0.0,-3.0};
  57. static GLfloat lightalpha=0.0;
  58.  
  59. static int fog=1;
  60. static int bfcull=1;
  61. static int usetex=1;
  62. static int help=1;
  63. static int joyavailable=0;
  64. static int joyactive=0;
  65.  
  66. static GLuint t1id,t2id;
  67. static GLuint teapotdlist,basedlist,lightdlist;
  68.  
  69. static float gettime(void)
  70. {
  71.   static clock_t told=0;
  72.   clock_t tnew,ris;
  73.  
  74.   tnew=clock();
  75.  
  76.   ris=tnew-told;
  77.  
  78.   told=tnew;
  79.  
  80.   return(ris/(float)CLOCKS_PER_SEC);
  81. }
  82.  
  83. static void calcposobs(void)
  84. {
  85.   dir[0]=sin(alpha*M_PI/180.0);
  86.   dir[1]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  87.   dir[2]=cos(beta*M_PI/180.0);
  88.  
  89.   obs[0]+=v*dir[0];
  90.   obs[1]+=v*dir[1];
  91.   obs[2]+=v*dir[2];
  92. }
  93.  
  94. static void special(int k, int x, int y)
  95. {
  96.   switch(k) {
  97.   case GLUT_KEY_LEFT:
  98.     alpha-=2.0;
  99.     break;
  100.   case GLUT_KEY_RIGHT:
  101.     alpha+=2.0;
  102.     break;
  103.   case GLUT_KEY_DOWN:
  104.     beta-=2.0;
  105.     break;
  106.   case GLUT_KEY_UP:
  107.     beta+=2.0;
  108.     break;
  109.   }
  110. }
  111.  
  112. static void key(unsigned char k, int x, int y)
  113. {
  114.   switch(k) {
  115.   case 27:
  116.     exit(0);
  117.     break;
  118.     
  119.   case 'a':
  120.     v+=0.005;
  121.     break;
  122.   case 'z':
  123.     v-=0.005;
  124.     break;
  125.  
  126.   case 'j':
  127.     joyactive=(!joyactive);
  128.     break;
  129.   case 'h':
  130.     help=(!help);
  131.     break;
  132.   case 'f':
  133.     fog=(!fog);
  134.     break;
  135.   case 't':
  136.     usetex=(!usetex);
  137.     break;
  138.   case 'b':
  139.     if(bfcull) {
  140.       glDisable(GL_CULL_FACE);
  141.       bfcull=0;
  142.     } else {
  143.       glEnable(GL_CULL_FACE);
  144.       bfcull=1;
  145.     }
  146.     break;
  147. #ifdef XMESA
  148.   case ' ':
  149.     XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
  150.     fullscreen=(!fullscreen);
  151.     break;
  152. #endif
  153.   }
  154. }
  155.  
  156. static void reshape(int w, int h) 
  157. {
  158.   WIDTH=w;
  159.   HEIGHT=h;
  160.   glMatrixMode(GL_PROJECTION);
  161.   glLoadIdentity();
  162.   gluPerspective(45.0,w/(float)h,0.2,40.0);
  163.   glMatrixMode(GL_MODELVIEW);
  164.   glLoadIdentity();
  165.   glViewport(0,0,w,h);
  166. }
  167.  
  168. static void printstring(void *font, char *string)
  169. {
  170.   int len,i;
  171.  
  172.   len=(int)strlen(string);
  173.   for(i=0;i<len;i++)
  174.     glutBitmapCharacter(font,string[i]);
  175. }
  176.  
  177. static void printhelp(void)
  178. {
  179.   glEnable(GL_BLEND);
  180.   glColor4f(0.5,0.5,0.5,0.5);
  181.   glRecti(40,40,600,440);
  182.   glDisable(GL_BLEND);
  183.  
  184.   glColor3f(1.0,0.0,0.0);
  185.   glRasterPos2i(300,420);
  186.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help");
  187.  
  188.   glRasterPos2i(60,390);
  189.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Togle Help");
  190.   glRasterPos2i(60,360);
  191.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"t - Togle Textures");
  192.   glRasterPos2i(60,330);
  193.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Togle Fog");
  194.   glRasterPos2i(60,300);
  195.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"b - Togle Back face culling");
  196.   glRasterPos2i(60,270);
  197.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate");
  198.   glRasterPos2i(60,240);
  199.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity");
  200.   glRasterPos2i(60,210);
  201.   printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity");
  202.  
  203.   glRasterPos2i(60,180);
  204.   if(joyavailable)
  205.     printstring(GLUT_BITMAP_TIMES_ROMAN_24,"j - Togle jostick control (Joystick control available)");
  206.   else
  207.     printstring(GLUT_BITMAP_TIMES_ROMAN_24,"(No Joystick control available)");
  208. }
  209.  
  210. static void drawbase(void)
  211. {
  212.   int i,j;
  213.   float x,y,dx,dy;
  214.  
  215.   glBindTexture(GL_TEXTURE_2D,t1id);
  216.  
  217.   dx=BASESIZE/BASERES;
  218.   dy=-BASESIZE/BASERES;
  219.   for(y=BASESIZE/2.0,j=0;j<BASERES;y+=dy,j++) {
  220.     glBegin(GL_QUAD_STRIP);
  221.     glColor3f(1.0,1.0,1.0);
  222.     glNormal3f(0.0,0.0,1.0);
  223.     for(x=-BASESIZE/2.0,i=0;i<BASERES;x+=dx,i++) {
  224.       glTexCoord2f(x,y);
  225.       glVertex3f(x,y,0.0);
  226.  
  227.       glTexCoord2f(x,y+dy);
  228.       glVertex3f(x,y+dy,0.0);
  229.     }
  230.     glEnd();
  231.   }
  232. }
  233.  
  234. static void drawteapot(void)
  235. {
  236.   static float xrot=0.0;
  237.   static float zrot=0.0;
  238.  
  239.   glPushMatrix();
  240.   glRotatef(lightalpha,0.0,0.0,1.0);
  241.   glMultMatrixf((GLfloat *)baseshadow);
  242.   glRotatef(-lightalpha,0.0,0.0,1.0);
  243.  
  244.   glTranslatef(0.0,0.0,1.0);
  245.   glRotatef(xrot,1.0,0.0,0.0);
  246.   glRotatef(zrot,0.0,0.0,1.0);
  247.  
  248.   glDisable(GL_TEXTURE_2D);
  249.   glDisable(GL_DEPTH_TEST);
  250.   glDisable(GL_LIGHTING);
  251.  
  252.   glColor3f(0.0,0.0,0.0);
  253.   glCallList(teapotdlist);
  254.  
  255.   glEnable(GL_DEPTH_TEST);
  256.   glEnable(GL_LIGHTING);
  257.   if(usetex)
  258.     glEnable(GL_TEXTURE_2D);
  259.  
  260.   glPopMatrix();
  261.  
  262.   glPushMatrix();
  263.   glTranslatef(0.0,0.0,1.0);
  264.   glRotatef(xrot,1.0,0.0,0.0);
  265.   glRotatef(zrot,0.0,0.0,1.0);
  266.  
  267.   glCallList(teapotdlist);
  268.   glPopMatrix();
  269.  
  270.   xrot+=2.0;
  271.   zrot+=1.0;
  272. }
  273.  
  274. static void drawlight1(void)
  275. {
  276.   glPushMatrix();
  277.   glRotatef(lightalpha,0.0,0.0,1.0);
  278.   glLightfv(GL_LIGHT0,GL_POSITION,lightpos);
  279.   glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightdir);
  280.  
  281.   glPopMatrix();
  282. }
  283.  
  284. static void drawlight2(void)
  285. {
  286.   glPushMatrix();
  287.   glRotatef(lightalpha,0.0,0.0,1.0);
  288.   glTranslatef(lightpos[0],lightpos[1],lightpos[2]);
  289.  
  290.   glDisable(GL_TEXTURE_2D);
  291.   glCallList(lightdlist);
  292.   if(usetex)
  293.     glEnable(GL_TEXTURE_2D);
  294.   
  295.   glPopMatrix();
  296.  
  297.   lightalpha+=1.0;
  298. }
  299.  
  300. static void dojoy(void)
  301. {
  302. #ifdef WIN32
  303.   static UINT max[2]={0,0};
  304.   static UINT min[2]={0xffffffff,0xffffffff},center[2];
  305.   MMRESULT res;
  306.   JOYINFO joy;
  307.  
  308.   res=joyGetPos(JOYSTICKID1,&joy);
  309.  
  310.   if(res==JOYERR_NOERROR) {
  311.     joyavailable=1;
  312.  
  313.     if(max[0]<joy.wXpos)
  314.       max[0]=joy.wXpos;
  315.     if(min[0]>joy.wXpos)
  316.       min[0]=joy.wXpos;
  317.     center[0]=(max[0]+min[0])/2;
  318.  
  319.     if(max[1]<joy.wYpos)
  320.       max[1]=joy.wYpos;
  321.     if(min[1]>joy.wYpos)
  322.       min[1]=joy.wYpos;
  323.     center[1]=(max[1]+min[1])/2;
  324.  
  325.     if(joyactive) {
  326.       if(fabs(center[0]-(float)joy.wXpos)>0.1*(max[0]-min[0]))
  327.     alpha-=2.5*(center[0]-(float)joy.wXpos)/(max[0]-min[0]);
  328.       if(fabs(center[1]-(float)joy.wYpos)>0.1*(max[1]-min[1]))
  329.     beta+=2.5*(center[1]-(float)joy.wYpos)/(max[1]-min[1]);
  330.  
  331.       if(joy.wButtons & JOY_BUTTON1)
  332.     v+=0.005;
  333.       if(joy.wButtons & JOY_BUTTON2)
  334.     v-=0.005;
  335.     }
  336.   } else
  337.     joyavailable=0;
  338. #endif
  339. }
  340.  
  341. static void draw(void)
  342. {
  343.   static int count=0;
  344.   static char frbuf[80];
  345.   float fr;
  346.  
  347.   dojoy();
  348.  
  349.   glEnable(GL_DEPTH_TEST);
  350.   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  351.  
  352.   if(usetex)
  353.     glEnable(GL_TEXTURE_2D);
  354.   else
  355.     glDisable(GL_TEXTURE_2D);
  356.  
  357.   if(fog)
  358.     glEnable(GL_FOG);
  359.   else
  360.     glDisable(GL_FOG);
  361.  
  362.   glEnable(GL_LIGHTING);
  363.  
  364.   glShadeModel(GL_SMOOTH);
  365.  
  366.   glPushMatrix();
  367.   calcposobs();
  368.  
  369.   gluLookAt(obs[0],obs[1],obs[2],
  370.         obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
  371.         0.0,0.0,1.0);
  372.  
  373.   drawlight1();
  374.   glCallList(basedlist);
  375.   drawteapot();
  376.   drawlight2();
  377.   glPopMatrix();
  378.   
  379.   if((count % FRAME)==0) {
  380.     fr=gettime();
  381.     sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  382.   }
  383.  
  384.   glDisable(GL_LIGHTING);
  385.   glDisable(GL_TEXTURE_2D);
  386.   glDisable(GL_DEPTH_TEST);
  387.   glDisable(GL_FOG);
  388.   glShadeModel(GL_FLAT);
  389.  
  390.   glMatrixMode(GL_PROJECTION);
  391.   glLoadIdentity();
  392.   glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  393.   glMatrixMode(GL_MODELVIEW);
  394.   glLoadIdentity();
  395.  
  396.   glColor3f(1.0,0.0,0.0);
  397.   glRasterPos2i(10,10);
  398.   printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  399.   glRasterPos2i(350,470);
  400.   printstring(GLUT_BITMAP_HELVETICA_10,"Teapot V1.2 Written by David Bucciarelli (tech.hmw@plus.it)");
  401.  
  402.   if(help)
  403.     printhelp();
  404.  
  405.   reshape(WIDTH,HEIGHT);
  406.  
  407.   glutSwapBuffers();
  408.  
  409.   count++;
  410. }
  411.  
  412. static void inittextures(void)
  413. {
  414.   IMAGE *img;
  415.   GLenum gluerr;
  416.   
  417.   glGenTextures(1,&t1id);
  418.   glBindTexture(GL_TEXTURE_2D,t1id);
  419.  
  420.   if(!(img=ImageLoad("tile.rgb"))) {
  421.     fprintf(stderr,"Error reading a texture.\n");
  422.     exit(-1);
  423.   }
  424.  
  425.   glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  426.   if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB,
  427.                    GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) {
  428.     fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
  429.     exit(-1);
  430.   }
  431.  
  432.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  433.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  434.   
  435.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  436.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  437.  
  438.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  439.  
  440.   glGenTextures(1,&t2id);
  441.   glBindTexture(GL_TEXTURE_2D,t2id);
  442.  
  443.   if(!(img=ImageLoad("bw.rgb"))) {
  444.     fprintf(stderr,"Error reading a texture.\n");
  445.     exit(-1);
  446.   }
  447.  
  448.   glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  449.   if((gluerr=gluBuild2DMipmaps(GL_TEXTURE_2D, 3, img->sizeX, img->sizeY, GL_RGB,
  450.                    GL_UNSIGNED_BYTE, (GLvoid *)(img->data)))) {
  451.     fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
  452.     exit(-1);
  453.   }
  454.  
  455.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  456.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
  457.   
  458.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  459.   glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
  460.  
  461.   glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  462. }
  463.  
  464. static void initlight(void)
  465. {
  466.   float lamb[4]={0.2,0.2,0.2,1.0};
  467.   float lspec[4]={1.0,1.0,1.0,1.0};
  468.  
  469.   glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,70.0);
  470.   glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,20.0);
  471.   glLightfv(GL_LIGHT0,GL_AMBIENT,lamb);
  472.   glLightfv(GL_LIGHT0,GL_SPECULAR,lspec);
  473.  
  474.   glMaterialf(GL_FRONT_AND_BACK,GL_SHININESS,20.0);
  475.   glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,lspec);
  476.  
  477.   glEnable(GL_LIGHT0);
  478. }
  479.  
  480. static void initdlists(void)
  481. {
  482.   GLUquadricObj *lcone,*lbase;
  483.   GLfloat plane[4];
  484.   GLfloat v0[3]={0.0,0.0,0.0};
  485.   GLfloat v1[3]={1.0,0.0,0.0};
  486.   GLfloat v2[3]={0.0,1.0,0.0};
  487.  
  488.   findplane(plane,v0,v1,v2);
  489.   shadowmatrix(baseshadow,plane,lightpos);
  490.  
  491.   teapotdlist=glGenLists(1);
  492.   glNewList(teapotdlist,GL_COMPILE);
  493.   glRotatef(90.0,1.0,0.0,0.0);
  494.   glCullFace(GL_FRONT);
  495.   glBindTexture(GL_TEXTURE_2D,t2id);
  496.   teapot(TEAPOTRES,0.6,GL_FILL);
  497.   glCullFace(GL_BACK);
  498.   glEndList();
  499.  
  500.   basedlist=glGenLists(1);
  501.   glNewList(basedlist,GL_COMPILE);
  502.   drawbase();
  503.   glEndList();
  504.  
  505.   lightdlist=glGenLists(1);
  506.   glNewList(lightdlist,GL_COMPILE);
  507.   glDisable(GL_LIGHTING);
  508.  
  509.   lcone=gluNewQuadric();
  510.   lbase=gluNewQuadric();
  511.   glRotatef(45.0,0.0,1.0,0.0);
  512.  
  513.   glColor3f(1.0,1.0,1.0);
  514.   glCullFace(GL_FRONT);
  515.   gluDisk(lbase,0.0,0.2,12.0,1.0);
  516.   glCullFace(GL_BACK);
  517.  
  518.   glColor3f(0.5,0.0,0.0);
  519.   gluCylinder(lcone,0.2,0.0,0.5,12,1);
  520.  
  521.   gluDeleteQuadric(lcone);
  522.   gluDeleteQuadric(lbase);
  523.  
  524.   glEnable(GL_LIGHTING);
  525.   glEndList();
  526. }
  527.  
  528. int main(int ac, char **av)
  529. {
  530.   float fogcolor[4]={0.025,0.025,0.025,1.0};
  531.  
  532.   fprintf(stderr,"Teapot V1.2\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");
  533.  
  534.   /*
  535.     if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
  536.     fprintf(stderr,"Error setting the process class.\n");
  537.     return 0;
  538.     }
  539.  
  540.     if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
  541.     fprintf(stderr,"Error setting the process priority.\n");
  542.     return 0;
  543.     }
  544.     */
  545.  
  546.   glutInitWindowPosition(0,0);
  547.   glutInitWindowSize(WIDTH,HEIGHT);
  548.   glutInit(&ac,av);
  549.  
  550.   glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);
  551.  
  552.   if(!(win=glutCreateWindow("Teapot"))) {
  553.     fprintf(stderr,"Error, couldn't open window\n");
  554.     return -1;
  555.   }
  556.  
  557.   reshape(WIDTH,HEIGHT);
  558.  
  559.   glShadeModel(GL_SMOOTH);
  560.   glEnable(GL_DEPTH_TEST);
  561.   glEnable(GL_CULL_FACE);
  562.   glEnable(GL_TEXTURE_2D);
  563.  
  564.   glEnable(GL_FOG);
  565.   glFogi(GL_FOG_MODE,GL_EXP2);
  566.   glFogfv(GL_FOG_COLOR,fogcolor);
  567.  
  568.   glFogf(GL_FOG_DENSITY,0.04);
  569. #ifdef FX
  570.   glHint(GL_FOG_HINT,GL_NICEST);
  571. #endif
  572.   glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  573.  
  574.   calcposobs();
  575.  
  576.   inittextures();
  577.   initlight();
  578.  
  579. #ifndef FX
  580.   glDisable(GL_TEXTURE_2D);
  581.   usetex=0;
  582. #endif
  583.  
  584.   initdlists();
  585.  
  586.   glClearColor(fogcolor[0],fogcolor[1],fogcolor[2],fogcolor[3]);
  587.  
  588.   glutReshapeFunc(reshape);
  589.   glutDisplayFunc(draw);
  590.   glutKeyboardFunc(key);
  591.   glutSpecialFunc(special);
  592.   glutIdleFunc(draw);
  593.  
  594.   glutMainLoop();
  595.  
  596.   return 0;
  597. }
  598.